GNU Radio中的流标签(Stream Tags)

您所在的位置:网站首页 radio tag GNU Radio中的流标签(Stream Tags)

GNU Radio中的流标签(Stream Tags)

2024-07-11 11:05| 来源: 网络整理| 查看: 265

目录

0、GR 中常用术语的官方解释

1、定义概述

2、在数据流中添加标签

3、添加标签的demo举例

4、从数据流中的获取标签

5、提取标签的demo举例

0、GR 中常用术语的官方解释

直接吧官方的解释抄过来,直接看英文更容易理解:

BlockA functional processing unit with inputs and outputsPortA single input or output of a blockSourceA producer of dataSinkA consumer of dataConnectionA flow of data from output port to input portFlow graphA collection of blocks and connectionsItemA unit of data. Ex: baseband sample, fft vector, matrix...StreamA continuous flow of consecutive itemsIO signatureA description of a blocks input and output ports 1、定义概述

流标签(Stream Tags)顾名思义就是为数据流中的特定 item (即数据项,数据项可以理解为一个数据单元,这个单元可以是一个向量、数组、一般的数据类型如 float、int、char 等类型的数据,一下简称数据)打上标签,用以标记我们认为的一些特殊的数据(比如幅值低于某个阈值的无效数据等),便于后续数据的处理。标签的形式是一个键值对(key:value pair),定义在块(block)的 work 函数中。其中键(key)指明了值(value)所代表的含义,值包含了这个标签里要传输的数据内容。键和值都是PMTs类型的数据,键是一个pmt symbol类型的数据,而值可以是任何数据类型的的pmt。另外,标签中还有一个额外的部分SrcID,也是pmt symbol类型的数据,指明了创建这个标签的块,一般是块的别名。

2、在数据流中添加标签

一个标签中需要包含四个部分:

1、偏置(offset):数据流中的标签需要使用绝对引用值。当某个数据流传输到某个block的work函数时,都会分配一个索引为0~N-1的缓冲区,该索引为数据流的相对索引。绝对索引值在数据流在流图开始运行时就开始计数了。可以通过以下两个c++ API来获取

unsigned long int nitems_read(unsigned int which_input); unsigned long int nitems_written(unsigned int which_output);

nitems_read用于输入数据流,nitems_written用于输出数据流。如果使用i代表输出数据的迭代索引,则将在输出端口的第nitems_written(0)+i个位置写入流标签。0代表第0个输出端口(the 0th output port)。 

2、键(key):表明标签数据类型的pmt symbol

3、值(value):标签所含的数据,pmt类型

4、源ID(srcid):可选参数。指明了创建标签的block,pmt symbol类型

C++中有两种添加标签的函数;

// 第一种,直接传入定义好的标签结构体 void add_item_tag(unsigned int which_output, const tag_t &tag); // 第二种,显式调用 void add_item_tag(unsigned int which_output, uint64_t abs_offset, const pmt::pmt_t &key, const pmt::pmt_t &value, const pmt::pmt_t &srcid=pmt::PMT_F);

第一种方式中是传入定义好的gr::tag_t结构体,第二种则是直接显式传入参数。

在Python中,可以调用如下方式添加标签(使用时注意参数数据类型):

add_item_tag(which_output, abs_offset, key, value) add_item_tag(which_output, abs_offset, key, value, srcid) 3、添加标签的demo举例

我们使用GNU Radio自带的嵌入Python块(embedded Python block)来举例说明添加标签的方式,加深理解。

该demo的作用是将输入向量(1, 2, 3, 4, 5, 6, 7)中值小于4的数据打上标签。嵌入Python块的命名为“add stream tag”,标签的key为"smaller than thr",value为小于阈值threshold的数。流图如下:

其中嵌入Python块的代码如下:

import numpy as np from gnuradio import gr import pmt class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block """Embedded Python Block example - a simple multiply const""" def __init__(self, threshold = 4.0): # only default arguments here """arguments to this function show up as parameters in GRC""" gr.sync_block.__init__( self, name='add stream tag', in_sig=[np.float32], out_sig=[np.float32] ) # 设置阈值 self.threshold = threshold def work(self, input_items, output_items): for index, sample in enumerate(input_items[0]): # print(sample) if sample < self.threshold: key = pmt.intern("smaller than thr") value = pmt.to_pmt(float(sample)) # 为模值小于添加标签 self.add_item_tag(0, # 将标签写到第0个输出端口 self.nitems_written(0) + index, # 绝对索引值 key, # 键 value) # 值 output_items[0][:] = input_items[0] return len(output_items[0])

运行流图,结果如下。可以看到,在向量中,小于4的元素1、2、3都被打上了标签。 

4、从数据流中的获取标签

在C++中在指定的数据流中的获取标签油两种API可以调用,起作用范围已在注释中标明:

// 1、获取数据在一个绝对索引值范围内的所有标签 void get_tags_in_range(。。。); // 2、获取数据在一个绝对索引值范围内的所有标签(范围限制在一个work函数内) void get_tags_in_window(。。。);

每一种API都有两种调用方式,以get_tags_in_range为例说明:

// 1、返回所给范围内的所有标签 void get_tags_in_range(std::vector &v, unsigned int which_input, uint64_t abs_start, uint64_t abs_end); // 2、返回所给范围内的指定键值的标签 void get_tags_in_range(std::vector &v, unsigned int which_input, uint64_t abs_start, uint64_t abs_end, const pmt::pmt_t &key);

注意第二种相比第一种多了个键值参数。

Python中的调用方式与C++略有不同,在Python中是返回一个符合条件的标签列表,如下:

tags = self.get_tags_in_window(which_input, rel_start, rel_end) 5、提取标签的demo举例

同上一个demo一样,这里仍用一个嵌入Python块来举例,加标签部分还使用3中的代码。

流图如下,流图中添加了一个用来读取标签的嵌入Python块,并命名为“read tags”。

该提取标签的block的代码如下:

import numpy as np from gnuradio import gr import pmt class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block """Embedded Python Block example - a simple multiply const""" def __init__(self): """arguments to this function show up as parameters in GRC""" gr.sync_block.__init__( self, name='read tags', # 模块命名 in_sig=[np.float32], # 输入数据类型 out_sig=None) def work(self, input_items, output_items): tags = self.get_tags_in_window(0, # 第0个输入端口 0, # 相对索引值下限 len(input_items[0])) # 相对索引值上限 for tag in tags: key = pmt.to_python(tag.key) # 将键由pmt转换为string value = pmt.to_python(tag.value)# 将键值由pmt转换为float print("(key: {} ; value: {})".format(key, value)) # 打印出键值对 return len(output_items[0])

结果显示如下,可以看出,打印出的tags完全符合3中的tag数据。

(参考:Stream Tags - GNU Radio)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3